package tw.right929.event
{
	import flash.events.Event;
	import flash.utils.Dictionary;
	
	/**
	 * 當想延遲屬性及方法產生的變動時，所使用的Event。
	 */
	public class ChangeEvent extends Event
	{
		private var _propertyChangeMap:Dictionary;
		private var _methodChangeMap:Dictionary;
		
		public function ChangeEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
		}
		
		/**
		 * 加入設定屬性產生的變化，如：addPropertyChange("x" , 10 , 20) ，代表x值從10變成20。
		 */
		public function addPropertyChange(property:String , oldValue:*=null , newValue:*=null):void
		{
			if(!_propertyChangeMap)
				_propertyChangeMap	=	new Dictionary();
			
			if(_propertyChangeMap[property])
				_propertyChangeMap[property].newValue	=	newValue;
			else
				_propertyChangeMap[property]	=	{oldValue:oldValue , newValue:newValue};
		}
		
		/**
		 * 查詢是否有這個屬性值的變動。
		 */
		public function hasPropertyChange(property:String):Boolean
		{
			if(_propertyChangeMap)
				return property in _propertyChangeMap;
			return false;
		}
		
		/**
		 * 取得屬性的新(newValue)、舊值(oldValue)。若沒有這個屬性的變動，傳回undefined。
		 * 請不要修改傳回的object會產生副作用。
		 */
		public function getPropertyChange(property:String):*
		{
			if(hasPropertyChange(property))
				return _propertyChangeMap[property];
			return undefined;
		}
		
		/**
		 * 加入呼叫方法產生的變化，如：addMethodChange("addChildAt" , {child:s , index:10}) ，代表因呼叫addChildAt(s , 10)所產生的變化。
		 */
		public function addMethodChange(method:String , methodArgs:*=null):void
		{
			if(!_methodChangeMap)
				_methodChangeMap	=	new Dictionary();
			
			if(_methodChangeMap[method])
			{
				if(methodArgs)
					_methodChangeMap[method].push(methodArgs);
			}
			else
			{
				_methodChangeMap[method]	=	new Array();
				if(methodArgs)
					_methodChangeMap[method].push(methodArgs);
			}
		}
		
		/**
		 * 查詢是否有因這個方法而產生的變動。
		 */
		public function hasMethodChange(method:String):Boolean
		{
			if(_methodChangeMap)
				return method in _methodChangeMap;
			return false;
		}
		
		/**
		 * 取得呼叫呼叫方法產生變動時參數清單的Array。若沒有這個方法的變動，傳回undefined。
		 * 請不要修改傳回的Array，會產生副作用。
		 * 例如：push(itme:Object)方法，執行了push(i1) , push(i2)，則getMethodChange傳回[{itme:i1},{item:i2}]。
		 */
		public function getMethodChange(method:String):Array
		{
			if(hasMethodChange(method))
				return _methodChangeMap[method];
			return undefined;
		}
		
		override public function clone() : Event
		{
			var e:ChangeEvent	=	 new ChangeEvent(type, bubbles, cancelable);
			e._propertyChangeMap	=	_propertyChangeMap;
			e._methodChangeMap	=	_methodChangeMap;
			return e;
		}
	}
}